package cn.xawl.interview.thread;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @author lh
 * @date 2020/08/25 13:19:15
 *
 * 集合不安全类(java.util.ConcurrentModificationException)
 * 1. ArrayList --> CopyOnWriteArrayList
 * 2. HashSet --> CopyOnWriteArraySet(实际上是一个CopyOnWriteArrayList)
 * 3. HashMap --> ConcurrentHashMap
 *
 **/
public class CollectionNoSafeDemo {



    public static void main(String[] args) {
        mapNoSafe();

    }

    private static void mapNoSafe() {
        Map<String, String> map = new ConcurrentHashMap<>();//Collections.synchronizedMap(new HashMap<>());//new HashMap<>();

        for (int i = 1; i <= 10; i++) {
            new Thread(() -> {
                map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 4));
                System.out.println(map);
            }, String.valueOf(i)).start();
        }
    }

    private static void setNoSafe() {
        /*
        *
        * HashSet底层是HashMap，它的set方法就是利用hashMap的put方法，key值为add的值，value值是一个Object常量
        * */

        Set<String> set = new CopyOnWriteArraySet<>();//Collections.synchronizedSet(new HashSet<>());//new HashSet<>();
        for (int i = 1; i <= 10; i++) {
            new Thread(() -> {
                set.add(UUID.randomUUID().toString().substring(0, 4));
                System.out.println(set);
            }, String.valueOf(i)).start();
        }
    }

    private static void listNoSafe() {

        /*
         * 解决异常步骤
         * 1. 故障现象
         * java.util.ConcurrentModificationException
         * 2. 导致原因
         *
         * 3. 解决方案
         *   3.1 new Vector<>()
         *   3.2 Collections.synchronizedList(new ArrayList<>())
         *   3.3 new CopyOnWriteList<>()，写时复制
         * 4. 优化
         * */

        List<String> list = new CopyOnWriteArrayList<>();//new Vector<>();//Collections.synchronizedList(new ArrayList<>()); //new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(0, 4));
                System.out.println(list);
            }, String.valueOf(i)).start();
        }
    }

}
